Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: fee estimation api #962

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

sylvaincormier
Copy link

Hi @jak-pan,

I’ve opened a draft PR that addresses #954 by introducing a runtime API for fee estimation. The API provides two key methods:

estimate_fee_payment(weight, account_id): Returns the correct asset and fee amount based on the given weight and the account’s configured currency.
estimate_fee_payment_for_extrinsic(encoded_extrinsic, account_id): Decodes the extrinsic, determines the applicable fees, and then provides the correct asset and amount.

I’ve also included extensive test coverage covering fallback scenarios (no price available), invalid extrinsic inputs, minimal weight fees, large extrinsics near max size, and account currency switching.

I made it a draft PR since there are only a few days left in the Kudos Carnival, and I wanted to ensure you have a chance to review and provide feedback before finalizing. Please let me know if any changes are needed. Thank you!

- Introduces runtime API to simplify fee payment calculation from weight+account_id or extrinsic+account_id.
- Integrates native and custom currency pricing.
- Adds tests covering fallback scenarios, large extrinsic handling, minimal weight fees, and currency switching.
@sylvaincormier sylvaincormier marked this pull request as draft December 12, 2024 21:16
@sylvaincormier sylvaincormier marked this pull request as ready for review December 17, 2024 11:28
Copy link
Contributor

@enthusiastmartin enthusiastmartin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thank you for your submission.

all-in-all, it could work but i have some suggestions - see comments below.

Other issue which I am not sure yet about is the place of the runtime api

It wont be definitely in the primives. I will update on this one.

use sp_weights::Weight;

sp_api::decl_runtime_apis! {
pub trait FeeEstimationApi<AccountId, AssetId, Balance>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Naming.

I would go with slightly different naming .

TransactionFeeAPI

and methods:

  • estimate_fee
  • estimate_uxt_fee

I let @jak-pan share his thoughts here on naming,

AssetId: Codec,
Balance: Codec,
{
fn estimate_fee_payment(weight: Weight, account_id: AccountId) -> (AssetId, Balance);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The result of both methods should return an Option.

In the actual implementation it seems it does unwrap_or in multiple places , so it can potentially return incorrect result, not the one you expect.

I would change the return value to be a struct. This would help with potential future extension if we want to include additional details.

fn estimate_fee_payment(weight: Weight, account_id: AccountId) -> (AssetId, Balance);

fn estimate_fee_payment_for_extrinsic(
uxt: BoundedVec<u8, MaxExtrinsicSize>,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to use boundedVec here and also no need for new constant.

Use the same as it is done in TransactionPaymentAPI.

`uxt: <Block as BlockT>::Extrinsic,`

@@ -450,19 +457,7 @@ use sp_core::OpaqueMetadata;
use xcm_fee_payment_runtime_api::Error as XcmPaymentApiError;

impl_runtime_apis! {
impl sp_api::Core<Block> for Runtime {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick: not sure what happened here but if possible, would you revert these changes

this PR should not touch/change anything else.

let native_fee = TransactionPayment::weight_to_fee(weight);

// Get the price of the account's currency if applicable
let price = MultiTransactionPayment::price(currency).unwrap_or(Price::one());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is not correct. if there is not price, it should not return anything, hence the comment about return an option.

let price = MultiTransactionPayment::price(currency).unwrap_or(Price::one());

// Calculate the final fee in the account's currency
let fee_in_currency = price.checked_mul_int(native_fee).unwrap_or(native_fee);
Copy link
Contributor

@enthusiastmartin enthusiastmartin Dec 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

again, if it fails - it returns incorrect info.

after you change, this should look something like :

`price.checked_mul_int(fee).map(|f| f.max(One::one()))`

we dont want to see 0 fee. this would be consistent with other stuff.


// Decode the extrinsic
let uxt = UncheckedExtrinsic::decode_all(&mut &uxt[..])
.expect("Invalid extrinsic provided");
Copy link
Contributor

@enthusiastmartin enthusiastmartin Dec 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this could cause panics easily.

there is not need to have boundedvev and and decode stuff. See my other comment to use differetn type for the paramter.

Comment on lines +1238 to +1241
let currency = MultiTransactionPayment::account_currency(&account_id);
let price = MultiTransactionPayment::price(currency).unwrap_or(Price::one());
let fee_in_currency = price.checked_mul_int(native_fee).unwrap_or(native_fee);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need to do this again - just call the other method.

@jak-pan jak-pan changed the title Issue 954 fee estimation api feat: fee estimation api Dec 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants